/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import React, { useState, useRef } from 'react';
import {
  View,
  Text,
  Image,
  StyleSheet,
  TouchableOpacity,
  Dimensions,
} from 'react-native';
import { songs, Track } from '../model';
import CurPlaySong from './CurPlaySong';
import musicPlayer from '../../util';
import {
  Menu,
  MenuOptions,
  MenuOption,
  MenuTrigger,
  MenuProvider,
  withMenuContext,
} from 'react-native-popup-menu';
import { PlayListPageConstants } from '../../util/constants.tsx';
import { useBreakpointValue } from '@hadss/react_native_adaptive_layout';
import {
  GestureDetector,
  Gesture,
  ViewWithMouseEvent,
} from '@hadss/react_native_uni_input';
import Animated, {
  useSharedValue,
  withSpring,
  runOnJS,
} from 'react-native-reanimated';

const SongListTable = ({ changePageShow }): JSX.Element => {
  const [currentSong, setCurrentSong] = useState<Track>(songs[0]);
  const [isPlaying, setIsPlaying] = useState<boolean>(false);
  const [currentIndex, setCurrentIndex] = useState(0);
  const isWide =
    Dimensions.get('screen').height >= 900 ||
    Dimensions.get('screen').width >= 900;

  // 滚动和轻扫--start
  const { height: SCREEN_HEIGHT } = Dimensions.get('window');
  // 用于跟踪滚动位置
  const translateY = useSharedValue(0);
  const startY = useRef(0);
  const totalHeight =
    (songs.length * PlayListPageConstants.ITEM_HEIGHT) / 2 -
    SCREEN_HEIGHT +
    270;

  // 轻扫
  const flingSongsList = Gesture.Fling()
    .direction('vertical')
    .minVelocity(800)
    .onStart((e) => {
      // rotation<0,表示从下往上滑动+rotation>0,表示从上往下滑动-数据，
      const { rotation } = e;
      const addListData =
        translateY.value - 10 * PlayListPageConstants.ITEM_HEIGHT;
      const removeListData =
        translateY.value + 10 * PlayListPageConstants.ITEM_HEIGHT;
      // 从下往上移动
      if (rotation < 0) {
        if (addListData >= -totalHeight) {
          // 若是没有到底，每次加10条数据的高度
          translateY.value = withSpring(addListData, { damping: 50 });
        } else {
          // 若是已经到底，不允许在轻扫
          translateY.value = withSpring(-totalHeight, { damping: 50 });
        }
      } else {
        // 从上往下移动
        if (removeListData < 0) {
          // 每次减10条数据数据的高度
          translateY.value = withSpring(removeListData, { damping: 50 });
        } else {
          // 若是已经到头，不允许在轻扫
          translateY.value = withSpring(0, { damping: 50 });
        }
      }
    });

  // 定义拖动手势
  const panSongsList = Gesture.Pan()
    .direction('vertical')
    .minDistance(150)
    .onStart((e) => {
      startY.current = translateY.value;
    })
    .onUpdate((e) => {
      // 更新滚动位置
      translateY.value = startY.current + e.translationY;
      // 限制滚动范围
      const maxTranslateY = 0;
      if (translateY.value > maxTranslateY) {
        // 从上往下拖动的最大值的限制
        translateY.value = withSpring(maxTranslateY, { damping: 50 });
      } else if (-(startY.current + e.translationY) > totalHeight) {
        // 从下往上拖动的最大值的限制
        translateY.value = withSpring(-totalHeight, { damping: 50 });
      }
    });
  // 列表滚动和轻扫 ==》end

  const [songsList, setSongsList] = useState(songs);
  // 删除数据
  const deleteItem = (index: number): void => {
    setSongsList((songsList) =>
      songsList.filter((_item, index1) => index1 !== index)
    );
  };
  // 收藏数据
  const collectItem = (index: number): void => {
    setSongsList((songsList) =>
      songsList.map((item1, index1) =>
        index1 === index ? { ...item1, hasCollect: true } : item1
      )
    );
  };
  // 取消收藏数据
  const deleteCollectItem = (index: number): void => {
    setSongsList((songsList) =>
      songsList.map((item1, index1) =>
        index1 === index ? { ...item1, hasCollect: false } : item1
      )
    );
  };

  // 鼠标是否悬浮
  const [hoverItem, setHoverItem] = useState(-1);

  const Openner = (props): JSX.Element => (
    <GestureDetector
      gesture={Gesture.LongPress().onStart((event): void => {
        props.ctx.menuActions.openMenu(props.name);
      })}
    >
      <ViewWithMouseEvent
        onMouseEvent={(event): void => {
          const mouseEventType = event.nativeEvent.action;
          const mouseEventButton = event.nativeEvent.button;
          if (mouseEventType === 2 && mouseEventButton === 2) {
            props.ctx.menuActions.openMenu(props.name);
          }
        }}
      >
        <Image source={require('../../../../asset/image/song_item_icon.svg')} />
      </ViewWithMouseEvent>
    </GestureDetector>
  );

  const ContextOpenner = withMenuContext(Openner);

  const renderItemGesture = (item: Track, index: number): JSX.Element => {
   return (
     <View style={styles.songInfo}>
       <GestureDetector
         gesture={Gesture.Exclusive(
           Gesture.Tap()
             .minPointers(1)
             .numberOfTaps(2)
             .onStart((): void => {
               changePageShow(false);
               musicPlayer.playTrackByIndex(item.songID, true);
               setCurrentSong(item);
             }),
           Gesture.Tap()
             .minPointers(1)
             .onStart(event => {
               changePageShow(false);
               musicPlayer.playTrackByIndex(item.songID, false);
               setCurrentSong(item);
             }),
         )}>
         <View style={{ flexDirection: 'row', top: 2, alignItems: 'center' }}>
           <GestureDetector
             gesture={Gesture.Hover().onHover((e): void => {
               setHoverItem(e.isHover ? index : -1);
             })}>
             <Text style={[styles.songTitle, hoverItem === index && styles.mouseHovered]}>{item.title}</Text>
           </GestureDetector>
           {/* 收藏的时候的爱心 */}
           <View style={{ width: 16 }}>
             {item.hasCollect ? <Image source={require('../../../../asset/image/music_love.svg')} style={{ width: 16, height: 14 }} /> : ''}
           </View>
         </View>
         <View style={{ flexDirection: 'row', top: 2 }}>
           {item.isVip ? <Text style={styles.songVIPAndAudioType}>VIP</Text> : ''}
           {item.audioType ? <Text style={styles.songVIPAndAudioType}>{item.audioType}</Text> : ''}
           <Text style={styles.songArtist}>{item.artist}</Text>
         </View>
       </GestureDetector>
     </View>
   ); 
  };

  const renderItem = (item: Track, index: number): JSX.Element => {
    return (
      <MenuProvider skipInstanceCheck={true}>
        <View style={styles.songItem}>
          {renderItemGesture(item, index)}
          <View style={styles.songIcon}>
            <ContextOpenner name={`menu_${index}`} />
            <Menu placement="top" name={`menu_${index}`}>
              <MenuTrigger></MenuTrigger>
              <MenuOptions optionsContainerStyle={[styles.optionList]}>
                <MenuOption onSelect={(): void => deleteItem(index)} style={styles.songMenuOption}>
                  <Image source={require('../../../../asset/image/delete.svg')} style={styles.songDelete} />
                  <Text>删除</Text>
                </MenuOption>
                {item.hasCollect ? (
                  <MenuOption onSelect={(): void => deleteCollectItem(index)} style={styles.songMenuOption}>
                    <Image source={require('../../../../asset/image/deleteCollect.svg')} style={styles.songDelete} />
                    <Text>移除收藏</Text>
                  </MenuOption>
                ) : (
                  <MenuOption onSelect={(): void => collectItem(index)} style={styles.songMenuOption}>
                    <Image source={require('../../../../asset/image/collect.svg')} style={styles.songDelete} />
                    <Text>收藏到歌单</Text>
                  </MenuOption>
                )}
              </MenuOptions>
            </Menu>
          </View>
        </View>
      </MenuProvider>
    );
  };

  return (
    <>
      <View style={styles.songPage}>
        <View style={styles.seachAndBack}>
          <View style={styles.backStyle}>
            <Image
              source={require('../../../../asset/image/back.png')}
              style={styles.backIconStyle}
            />
            <Text style={styles.collectionMusic}>收藏</Text>
          </View>
          <View style={styles.seachOut}>
            <Image
              source={require('../../../../asset/image/seachIcon.svg')}
              style={styles.seachIcon}
            />
            <Text style={styles.seachContent}>搜索歌曲、歌手…</Text>
          </View>
        </View>

        <View style={styles.playlistInfo}>
          {PlayListPageConstants.optionsBtn.map((item, index) => (
            <View key={index}>
              <TouchableOpacity
                style={[
                  styles.customButton,
                  {
                    backgroundColor:
                      index === 0 ? 'rgb(255, 25, 73)' : 'rgb(255, 255, 255)',
                  },
                ]}
                onPress={(): void => {}}
              >
                <Text
                  style={[
                    styles.buttonText,
                    {
                      color:
                        index === 0
                          ? 'rgb(255, 255, 255)'
                          : 'rgba(0, 0, 0, 0.6)',
                    },
                  ]}
                >
                  {item.name}
                </Text>
              </TouchableOpacity>
            </View>
          ))}
        </View>
        <View style={{ flex: 1, flexDirection: 'row', top: 8 }}>
          <View style={{ flex: 1 }}>
            <View style={styles.listHeader}>
              <Image
                source={require('../../../../asset/image/play_icon.svg')}
                style={styles.listHeaderImage}
              />
              <Text style={styles.listHeaderText}>{'播放全部'}</Text>
              <View style={{ flex: 1 }} />
              <Image
                source={require('../../../../asset/image/allData.png')}
                style={styles.openIcon}
              />
            </View>
            <View style={{ flex: 1, overflow: 'hidden' }}>
              <GestureDetector
                gesture={Gesture.Exclusive(flingSongsList, panSongsList)}
              >
                <Animated.View
                  style={[
                    styles.containerList,
                    { transform: [{ translateY: translateY }] },
                  ]}
                  pointerEvents={'box-none'}
                >
                  {songsList.map((item, index) => (
                    <View key={index} style={styles.songsItem}>
                      {renderItem(item, index)}
                    </View>
                  ))}
                </Animated.View>
              </GestureDetector>
            </View>
          </View>
        </View>
      </View>
      <CurPlaySong
        song={currentSong}
        setCurrentSong={setCurrentSong}
        isPlaying={isPlaying}
        setIsPlaying={setIsPlaying}
        changePageShow={changePageShow}
      />
    </>
  );
};

const styles = StyleSheet.create({
  songPage: {
    flex: 1,
    marginLeft: 24,
    marginRight: 24,
  },
  containerList: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    padding: 10,
  },
  songItem: {
    flexDirection: 'row',
    borderBottomWidth: 1,
    borderBottomColor: '#ddd',
    height: 64,
    alignItems: 'center',
    justifyContent: 'space-between',
    paddingHorizontal: 8,
  },
  songsItem: {
    width: '50%',
    height: PlayListPageConstants.ITEM_HEIGHT,
    justifyContent: 'center',
    paddingLeft: 16,
    borderBottomWidth: 1,
    borderBottomColor: '#eee',
  },
  songInfo: {
    flexDirection: 'column',
    justifyContent: 'center',
    flex: 1,
  },
  songTitle: {
    fontSize: 16,
    fontWeight: '500',
    lineHeight: 21,
    color: 'rgba(0, 0, 0, 0.9)',
  },
  songArtist: {
    fontSize: 12,
    color: 'rgba(0, 0, 0, 0.4)',
    left: 4,
    lineHeight: 16,
  },
  songVIPAndAudioType: {
    color: 'rgb(128, 101, 64)',
    fontSize: 10,
    lineHeight: 16,
    height: 16,
    backgroundColor: 'rgba(199, 158, 99, 0.2)',
    borderRadius: 4,
    marginRight: 8,
    verticalAlign: 'middle',
    paddingHorizontal: 4,
  },
  songIcon: {
    width: 20,
    height: 20,
  },
  acoustic: {
    width: 16,
    height: 16,
  },
  listHeader: {
    height: 48,
    flexDirection: 'row',
    alignItems: 'center',
  },
  listHeaderImage: {
    width: 32,
    height: 32,
  },
  listHeaderText: {
    left: 8,
    fontSize: 18,
    color: 'rgba(0, 0, 0, 0.9)',
    fontWeight: '700',
    lineHeight: 24,
  },
  openIcon: {
    width: 20,
    height: 20,
    right: 15,
  },
  collectionMusic: {
    color: 'rgba(0, 0, 0, 0.9)',
    fontWeight: '700',
    fontSize: 20,
    marginTop: 10,
    marginLeft: 8,
  },
  playlistInfo: {
    flexDirection: 'row',
  },
  customButton: {
    width: 157,
    height: 36,
    padding: 10,
    borderRadius: 18,
    marginRight: 8,
    justifyContent: 'center',
    alignItems: 'center',
  },
  buttonText: {
    color: 'rgba(0, 0, 0, 0.9)',
  },
  songDelete: {
    width: 12,
    height: 14,
    marginRight: 6,
  },
  songMenuOption: {
    flexDirection: 'row',
  },
  optionList: {
    width: 128,
    borderRadius: 20,
    paddingVertical: 4,
    paddingHorizontal: 16,
    color: 'rgba(0, 0, 0, 0.9)',
  },
  seachAndBack: {
    flexDirection: 'row',
  },
  backStyle: {
    flexDirection: 'row',
    height: 56,
    flex: 1,
  },
  backIconStyle: {
    width: 40,
    height: 40,
  },
  seachOut: {
    flexDirection: 'row',
    borderRadius: 24,
    backgroundColor: 'rgba(0, 0, 0, 0.05)',
    width: 352,
    height: 40,
    lineHeight: 40,
    fontSize: 16,
    paddingLeft: 12,
  },
  seachContent: {
    lineHeight: 40,
    color: 'rgba(0, 0, 0, 0.6)',
  },
  seachIcon: {
    width: 15,
    height: 15,
    top: 13,
    marginRight: 12,
  },
  mouseHovered: {
    fontSize: 20,
  },
});

export default React.memo(SongListTable);
